<template>
  <div>
    <PlusTable :columns="tableConfig" :table-data="tableData" :default-size="'small'"
               :pagination="{
                  total,
                  modelValue: pageInfo,
                  pageSizeList: [10, 20, 50, 100],
                  align: 'right'
                }"
               @paginationChange="handlePaginationChange">
      <template v-slot:title>
        <el-button
            type="primary"
            @click="exportToExcel"
            class="mb-4"
        >
          <!-- 用 el-icon 包裹图标组件，组件名是 ElIconDownload（驼峰命名） -->
          <el-icon>
            <el-icon-download/>
          </el-icon>
          导出 Excel
        </el-button>
      </template>
    </PlusTable>
  </div>
</template>

<script setup lang="ts">
import type {SaleData} from "../model/sale.ts";
import {ref, watch} from "vue";
import {type PageInfo, type PlusColumn, PlusTable, useTable} from "plus-pro-components";
import type {TableColumnCtx} from "element-plus";
import * as XLSX from 'xlsx';
import {ElMessage} from 'element-plus';

const props = defineProps({
  rawList: {
    type: Array<SaleData>,
    required: true
  }
})
const totalTableDatas = ref<SaleData[]>([])

const filterHandler = (
    value: string,
    row: SaleData,
    column: TableColumnCtx<SaleData>
) => {
  const property = column['property']
  return row[property] === value
}

const {tableData, total, pageInfo} = useTable<SaleData[]>()

const handlePaginationChange = (_pageInfo: PageInfo): void => {
  pageInfo.value = _pageInfo
  const {page, pageSize} = _pageInfo;
  const startIndex = (page - 1) * pageSize;
  const endIndex = startIndex + pageSize;
  tableData.value = totalTableDatas.value.slice(startIndex, endIndex);
}

const tableConfig: PlusColumn[] = [
  {label: '交易时间', width: 120, prop: 'sale_date', exportLabel: '交易时间'},
  {label: '品牌', width: 80, prop: 'brand', exportLabel: '品牌'},
  {label: '门店', width: 280, prop: 'store_name', exportLabel: '门店'},
  {label: '药品', width: 70, prop: 'medicine', exportLabel: '药品'},
  {label: '销售数量', width: 100, prop: 'sale_total', exportLabel: '销售数量'},
  {label: '省', width: 100, prop: 'province', exportLabel: '省'},
  {label: '市', width: 100, prop: 'city', exportLabel: '市'},
  {label: '区/县', width: 80, prop: 'district', exportLabel: '区/县'},
  {label: '经纬度', width: 200, prop: 'location', exportLabel: '经纬度'},
  {label: '销售代表', width: 200, prop: 'sales_rep', exportLabel: '销售代表'}
]

watch(
    () => props.rawList,
    (newVal) => {
      if (newVal) {
        totalTableDatas.value = newVal;
        pageInfo.value.page = 1;
        handlePaginationChange(pageInfo.value);
        total.value = newVal.length
      }
    },
    {immediate: false}
)

const exportToExcel = () => {
  const exportData = totalTableDatas.value;

  if (!exportData || exportData.length === 0) {
    ElMessage.warning('没有数据可以导出！');
    return;
  }

  const exportColumns = tableConfig
      .filter(col => col.prop)
      .map(col => ({
        prop: col.prop,
        label: col.exportLabel || col.label
      }));

  const worksheetData = [
    exportColumns.map(col => col.label)
  ];

  exportData.forEach(item => {
    const row = exportColumns.map(col => {
      if (col.prop === 'sale_date' && item[col.prop]) {
        return new Date(item[col.prop]).toLocaleDateString('zh-CN');
      }
      return item[col.prop] ?? '';
    });
    worksheetData.push(row);
  });

  const workbook = XLSX.utils.book_new();
  const worksheet = XLSX.utils.aoa_to_sheet(worksheetData);
  XLSX.utils.book_append_sheet(workbook, worksheet, '销售数据');

  const excelBuffer = XLSX.write(workbook, {bookType: 'xlsx', type: 'array'});
  const blob = new Blob([excelBuffer], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});

  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `销售数据汇总_${new Date().toISOString().split('T')[0]}.xlsx`;
  document.body.appendChild(a);
  a.click();

  document.body.removeChild(a);
  URL.revokeObjectURL(url);

  ElMessage.success('Excel 文件已开始下载！');
};
</script>

<style scoped>
</style>